package org.softmed.rest.editor.comps.utils.list;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import net.miginfocom.swing.MigLayout;

import org.restlet.Client;
import org.restlet.data.Response;
import org.softmed.rest.editor.EditorUtil;
import org.softmed.rest.editor.FilePathAware;
import org.softmed.rest.editor.FilePathProvider;
import org.softmed.rest.editor.commons.SwingUtil;
import org.softmed.rest.editor.comps.SimpleEditor;
import org.softmed.swing.IconManager;

public class ListFieldPanel extends JPanel implements ActionListener,
		showListFieldDetails, FilePathAware {

	JButton minMax = new JButton(IconManager.listRemove);
	JButton deleteAll = new JButton(IconManager.remove);

	ListAddingPanel listAddingPanel;
	PagedListPanel pagedListPanel;

	// JLabel count = new JLabel();
	String uriFieldName;
	SimpleEditor parentEditor;
	Class editorClass;
	private JPanel panel;

	// FilePathProvider filePathProvider;

	public ListFieldPanel(String label, String uriFieldName, Class editorClass,
			SimpleEditor parent, boolean useTitleFont) throws Throwable {
		setup(label, uriFieldName, editorClass, parent, useTitleFont);
	}

	public ListFieldPanel(String label, String uriFieldName, Class editorClass,
			SimpleEditor parent) throws Throwable {
		setup(label, uriFieldName, editorClass, parent, true);
	}

	public void setup(String label, String uriFieldName, Class editorClass,
			SimpleEditor parent, boolean useTitleFont) throws Throwable {
		// setBorder(BorderFactory.createLineBorder(Color.RED));
		// setBorder(BorderFactory.createEtchedBorder());

		// minMax.setBorder(null);
		// deleteAll.setBorder(null);
		// this.filePathProvider = provider;
		this.editorClass = editorClass;
		this.parentEditor = parent;
		this.uriFieldName = uriFieldName;

		if (!SimpleEditor.class.isAssignableFrom(editorClass))
			throw new RuntimeException(
					"Editor class for field must be a SimpleEditor");

		minMax.setBorder(BorderFactory.createLineBorder(Color.GRAY));
		deleteAll.setBorder(BorderFactory.createLineBorder(Color.GRAY));

		minMax.setToolTipText("Show list content");
		deleteAll
				.setToolTipText("Remove all objects in list. The objects aren't deleted, just removed from this particular list.");

		SwingUtil.setSize(minMax, EditorUtil.buttonHeightAndWidth,
				EditorUtil.buttonHeightAndWidth);
		SwingUtil.setSize(deleteAll, EditorUtil.buttonHeightAndWidth,
				EditorUtil.buttonHeightAndWidth);
		// SwingUtil.setSize(minimize, 15, 15);
		// minimize.setVisible(false);

		panel = new JPanel();
		MigLayout layout = new MigLayout("left, insets "
				+ EditorUtil.smallestInsets + ", gap 0");
		panel.setLayout(layout);
//		panel.add(minMax);
		// panel.add(minimize);
		JLabel title = new JLabel(label);
		panel.add(Box.createHorizontalStrut(5));
		if (useTitleFont)
			title.setFont(SwingUtil.editorTitleFont);
		panel.add(title, "w 90!");
		// panel.add(count, "h 35!");
		// panel.add(new JLabel("Objects"), "w 60!");

		add(panel);

		BoxLayout box = new BoxLayout(this, BoxLayout.PAGE_AXIS);
		setLayout(box);

		minMax.addActionListener(this);
		// minimize.addActionListener(this);
		deleteAll.addActionListener(this);

		minMax.setActionCommand("minimize");

		pagedListPanel = new PagedListPanel(parentEditor.getUriProvider(), this);
		listAddingPanel = new ListAddingPanel(label, uriFieldName, editorClass,
				parent, pagedListPanel, this);

		panel.add(pagedListPanel.getInfoBar());
		panel.add(listAddingPanel);
		panel.add(Box.createHorizontalStrut(19));

		panel.add(listAddingPanel.getDetailToggle(), "");
		panel.add(deleteAll, "");
		
		panel.add(minMax);

		// add(listAddingPanel);
		add(pagedListPanel);

		panel.setBackground(Color.WHITE);
		setBackground(Color.WHITE);

		// showListFieldDetails();
		hideListFieldDetails();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		try {

			String command = e.getActionCommand();

			if (command.equals("remove") || command.equals("delete")
					|| command.equals("deleteAll")) {
				EditorUtil.showUpdatePanel();

				JButton button = (JButton) e.getSource();
				SimpleEditor childEditor = (SimpleEditor) button.getParent()
						.getParent();

				int index = this.pagedListPanel.itemList.editors
						.indexOf(childEditor);
				long pageNumber = this.pagedListPanel.pagedList
						.getCurrentPageNumber();
				long itemsPerPage = this.pagedListPanel.pagedList
						.getItemsPerPage();

				long x = (pageNumber - 1) * itemsPerPage;
				long childListIndex = x + (index + 1);

				String indexToDelete = pagedListPanel.getBaseURI() + "/"
						+ childListIndex;

				// String index = button.getName();
				// String indexToDelete = pagedListPanel.getBaseURI() + "/"
				// + index;
				Response response = parentEditor.getClient().delete(
						indexToDelete);

				if (response.getStatus().getCode() != 200) {
					EditorUtil.hideUpdatePanel();
					throw new RuntimeException("couldn't delete list index "
							+ indexToDelete);
				}

				long possibleItemsInPage = pageNumber * itemsPerPage;

				long currentItemCount = this.pagedListPanel.pagedList
						.getItemCount();

				// int indexOfStructToRemove = index * 2 + 1;

				// childEditor.remo
				pagedListPanel.itemList.removeEditor(childEditor);

				if (currentItemCount > possibleItemsInPage) {
					// go fetch the last guy and add to list !!!
					String lastChildToFetch = pagedListPanel.getBaseURI() + "/"
							+ possibleItemsInPage;

					response = parentEditor.getClient().get(lastChildToFetch);
					if (response.getStatus().getCode() != 200) {
						EditorUtil.hideUpdatePanel();
						throw new RuntimeException(
								"couldn't get list item URI "
										+ lastChildToFetch);
					}

					String lastChildInPageURI = response.getEntity().getText();

					childEditor.loadEntity(lastChildInPageURI);

					pagedListPanel.itemList
							.addSimpleNonEnabledEditor(childEditor.getEntity());

				}

				// refresh the nav header
				if (index == 0) {
					if (pagedListPanel.pagedList.getCurrentPageNumber() > 1) {
						pagedListPanel.pagedList
								.setCurrentPageNumber((int) (pagedListPanel.pagedList
										.getCurrentPageNumber() - 1));
						// fetch previous list
						pagedListPanel.openURI(pagedListPanel.pagedList
								.getPreviousURI());
					} else {
						pagedListPanel.pagedList.setCurrentPageNumber(1);
						pagedListPanel.decreaseListContent();
					}
				} else
					pagedListPanel.decreaseListContent();

				EditorUtil.hideUpdatePanel();
				revalidate();

				// go fetch the last guy in the list

				// pagedListPanel.refresh();

				// count
				// .setText(""
				// + pagedListPanel.getPagedList().getItemCount());
				return;
			}
			//
			// if (command.equals("delete") || command.equals("deleteAll")) {
			// pagedListPanel.refresh();
			// // count
			// // .setText(""
			// // + pagedListPanel.getPagedList().getItemCount());
			// return;
			// }

			if (command.equals("maximize")) {
				showListFieldDetails();
				// minMax.setIcon(IconManager.removeMinus);
				// minMax.setActionCommand("minimize");
				listAddingPanel.enabled();
				// pagedListPanel.getInfoBar().setVisible(true);
				return;
			}

			if (command.equals("minimize")) {
				hideListFieldDetails();
				// minMax.setIcon(IconManager.add);
				// minMax.setActionCommand("maximize");
				listAddingPanel.disabled();

				return;
			}

			Object source = e.getSource();
			if (source == deleteAll) {

				int duh = JOptionPane
						.showConfirmDialog(
								this,
								"WARNING\n"
										+ "This will remove all the objects in the list.\n"
										+ "Are you sure you want to proceed?",
								"WARNING", JOptionPane.YES_NO_OPTION,
								JOptionPane.QUESTION_MESSAGE);
				if (duh == JOptionPane.NO_OPTION)
					return;
				EditorUtil.showUpdatePanel();
				Client client = parentEditor.getClient();
				Response response = client.delete(parentEditor.getEntityURI()
						+ "/" + uriFieldName + "?detailed");
				EditorUtil.hideUpdatePanel();
				pagedListPanel.refresh();
				// count
				// .setText(""
				// + pagedListPanel.getPagedList().getItemCount());

				if (response.getStatus().getCode() != 200)
					throw new RuntimeException("couldn't delete list "
							+ uriFieldName + " from "
							+ parentEditor.getEntityURI());

				return;
			}

		} catch (Throwable t) {
			EditorUtil.hideUpdatePanel();
			t.printStackTrace();
			JOptionPane.showMessageDialog(this, t.getMessage(), "Error",
					JOptionPane.ERROR_MESSAGE);
		}

	}

	// public JLabel getCount() {
	// return count;
	// }

	@Override
	public void hideListFieldDetails() {
		listAddingPanel.setVisible(false);
		pagedListPanel.setVisible(false);
		deleteAll.setVisible(false);
		listAddingPanel.getDetailToggle().setVisible(false);
		minMax.setIcon(IconManager.listAdd);
		minMax.setToolTipText("Show list content");
		minMax.setActionCommand("maximize");
		pagedListPanel.getInfoBar().setVisible(false);
	}

	@Override
	public void showListFieldDetails() throws Throwable {
		setEntityRefresh();
		listAddingPanel.setVisible(true);
		pagedListPanel.setVisible(true);
		deleteAll.setVisible(true);
		listAddingPanel.getDetailToggle().setVisible(true);
		minMax.setToolTipText("Hide list content");
		minMax.setIcon(IconManager.listRemove);
		minMax.setActionCommand("minimize");
		pagedListPanel.getInfoBar().setVisible(true);

	}

	public void setEntityRefresh() throws Throwable {

		String fieldURI = parentEditor.getEntityURI() + "/" + uriFieldName;
		pagedListPanel.setBaseClassURI(fieldURI);
		// count.setText("" + pagedListPanel.getPagedList().getItemCount());
	}

	@Override
	public void setFilePathProvider(FilePathProvider provider) {
		pagedListPanel.setFilePathProvider(provider);

	}

	public void setFullBackground(Color color) {
		panel.setBackground(color);
		setBackground(color);
		listAddingPanel.setFullBackground(color);
		// pagedListPanel.getInfoBar().setBackground(color);
		// pagedListPanel.getInfoBar().getNavBar().setBackground(color);
		pagedListPanel.setFullBackground(color);
	}

	public void setChildrenEditorBackground(Color color) {
		pagedListPanel.setChildrenEditorBackground(color);

	}

}
